#include "stdafx.h"
#include "3DViewerTextureManager.h"


CTexture* CTextureManager::FindTexture(CString URI)
{
	TRACE("CTextureManager::FindTexture");

	std::list<CTexture*>::iterator it = m_textures.begin();
	for (; it != m_textures.end(); ++it)
	{
		if (URI == (*it)->m_URI)
			return *it;
	}
	return NULL;
}



CTexture* CTextureManager::AddTexture(CModel *model, CString URI)
{
	TRACE("CTextureManager::AddTexture");

	CTexture *texture = FindTexture(URI); 
	if (texture == NULL)
	{
		texture = new CTexture;
		texture->m_URI = URI;

/*		FIBITMAP *image = NULL;

		// Open image via http connection
		if (URI.Left(7) == "http://" || URI.Left(7) == "HTTP://" || URI.Left(7) == "Http://")
		{
			CInternetSession *session = new CInternetSession();

			CStdioFile *file = session->OpenURL(URI.GetBuffer(), 1, INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD);	
			BYTE *buf = new BYTE[500000];

			int n = 0, i = 0;
			while (n = file->Read(&buf[i], 1024))
				i += n;

			FIMEMORY *mem =  FreeImage_OpenMemory(buf, i);

			if (URI.Right(4) == "jpeg" || URI.Right(3) == "jpg" || URI.Right(3) == "JPG" || URI.Right(3) == "Jpg")
				image = FreeImage_LoadFromMemory(FIF_JPEG, mem);
			else if (URI.Right(3) == "png" || URI.Right(3) == "PNG" || URI.Right(3) == "Png")
				image = FreeImage_LoadFromMemory(FIF_PNG, mem);
			else 
			{
				delete texture;
				return NULL;
			}
		}

		// Open image from a local folder 
		else
		{
			//image format
			FREE_IMAGE_FORMAT format;

			//check the file signature and deduce its format
			format = FreeImage_GetFileType(URI.GetBuffer(), 0);

			//if unknown, try to guess the file format from the file extension
			if (format == FIF_UNKNOWN) 
				format = FreeImage_GetFIFFromFilename(URI.GetBuffer());

			//check that the plugin has reading capabilities and load the file
			if (format != FIF_UNKNOWN && FreeImage_FIFSupportsReading(format))
				image = FreeImage_Load(format, URI.GetBuffer());
		}

		if (image != NULL)
		{
			//retrieve the image data
			//get the image width and height
			texture->m_ImageWidth = FreeImage_GetWidth(image);
			texture->m_ImageHeight = FreeImage_GetHeight(image);
			texture->m_ImageData = FreeImage_GetBits(image);
			if (FreeImage_GetRedMask(image) & 1)
				texture->m_ImageFormat = GL_RGB;
			else
				texture->m_ImageFormat = GL_BGR_EXT;

			texture->m_OpenglId = ((C3DViewerView*)((CMainFrame*)AfxGetMainWnd())->MDIGetActive())->AddTexture(texture->m_ImageWidth, texture->m_ImageHeight, texture->m_ImageFormat, texture->m_ImageData);

			/*
			glGenTextures(1, &texture->m_OpenglId);
			glBindTexture(GL_TEXTURE_2D, texture->m_OpenglId);
			glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

			if (FreeImage_GetRedMask(image) & 1)
				glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture->m_ImageWidth, texture->m_ImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, texture->m_ImageData);
			else
				glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture->m_ImageWidth, texture->m_ImageHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, texture->m_ImageData);
*
			//Free FreeImage's copy of the data
			FreeImage_Unload(image);
		}
*/
		texture->m_OpenglId = 0;
		texture->m_changed = true;
		m_textures.push_back(texture);
	}

	if (model != NULL)
		texture->m_usedByModels.push_back(model);	
	return texture;
}

bool CTextureManager::RemoveTexture(CModel *model, CTexture *texture)
{
	TRACE("CTextureManager::RemoveTexture");

	if (model != NULL)
		texture->m_usedByModels.remove(model);

	if (texture->m_usedByModels.size() == 0)
	{
		m_textures.remove(texture);

		// To do (delete data)
		if (texture->m_URI)
			delete[] texture->m_URI;
//		if (texture->m_ImageData)
//			delete[] texture->m_ImageData;

		m_deletedTextures.push_back(texture->m_OpenglId);

		delete texture;
		return true;
	}
	return false;
}

void CTextureManager::ChangeTexture(CTexture* texture, CString URI)
{
	TRACE("CTextureManager::ChangeTexture");

//	FIBITMAP *image = NULL;

	// Open image via http connection
/*	if (URI.Left(7) == "http://" || URI.Left(7) == "HTTP://" || URI.Left(7) == "Http://")
	{
		CInternetSession *session = new CInternetSession();

		CStdioFile *file = session->OpenURL(URI.GetBuffer(), 1, INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD);	
		BYTE *buf = new BYTE[500000];

		int n = 0, i = 0;
		while (n = file->Read(&buf[i], 1024))
			i += n;

		FIMEMORY *mem =  FreeImage_OpenMemory(buf, i);

		if (URI.Right(4) == "jpeg" || URI.Right(3) == "jpg" || URI.Right(3) == "JPG" || URI.Right(3) == "Jpg")
			image = FreeImage_LoadFromMemory(FIF_JPEG, mem);
		else if (URI.Right(3) == "png" || URI.Right(3) == "PNG" || URI.Right(3) == "Png")
			image = FreeImage_LoadFromMemory(FIF_PNG, mem);
		else 
		{
			return;
		}
	}

	// Open image from a local folder 
	else
	{
		//image format
		FREE_IMAGE_FORMAT format;

		//check the file signature and deduce its format
		format = FreeImage_GetFileType(URI.GetBuffer(), 0);

		//if unknown, try to guess the file format from the file extension
		if (format == FIF_UNKNOWN) 
			format = FreeImage_GetFIFFromFilename(URI.GetBuffer());

		//check that the plugin has reading capabilities and load the file
		if (format != FIF_UNKNOWN && FreeImage_FIFSupportsReading(format))
			image = FreeImage_Load(format, URI.GetBuffer());
	}

	if (image != NULL)
	{
		//retrieve the image data
		//get the image width and height
		texture->m_ImageWidth = FreeImage_GetWidth(image);
		texture->m_ImageHeight = FreeImage_GetHeight(image);
		
		texture->m_ImageData = FreeImage_GetBits(image);
		if (FreeImage_GetRedMask(image) & 1)
			texture->m_ImageFormat = GL_RGB;
		else
			texture->m_ImageFormat = GL_BGR_EXT;

//		ReplaceTexture();
/*
		glDeleteTextures(1, &texture->m_OpenglId); 
		glBindTexture(GL_TEXTURE_2D, texture->m_OpenglId);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

		if (FreeImage_GetRedMask(image) & 1)
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture->m_ImageWidth, texture->m_ImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, texture->m_ImageData);
		else
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture->m_ImageWidth, texture->m_ImageHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, texture->m_ImageData);
*
		//Free FreeImage's copy of the data
		FreeImage_Unload(image);
*/
		texture->m_URI = URI;
		texture->m_changed = true;
//	}
}

/*
unsigned int COpenGLView::AddTexture(int width, int height, int format, BYTE *data)
{
	unsigned int id;
	glGenTextures(1, &id);
	glBindTexture(GL_TEXTURE_2D, id);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, data);
	return id;
}

void COpenGLView::ReplaceTexture(unsigned int id, int width, int height, int format, BYTE *data)
{
	glDeleteTextures(1, &id); 
	glBindTexture(GL_TEXTURE_2D, id);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, data);
//	return id;
}
*/